# -*- coding: utf-8 -*-
""" 
ASR服务核心应用，负责实例管理和Flask初始化
"""

import werkzeug.utils
import os
from datetime import timedelta
import odd_asr_exceptions
import odd_asr_config as config
from flask import Flask

from log import logger
from odd_asr import OddAsrFile, OddAsrParamsFile

# 全局变量：ASR实例参数和实例集合
odd_asr_params_file = OddAsrParamsFile()
odd_asr_file_set = set()  # 存储所有ASR文件识别实例


def init_instance_file():
    """初始化ASR文件识别实例，根据配置创建指定数量的实例"""
    global odd_asr_file_set
    odd_asr_file_set.clear()  # 清空旧实例
    max_instance = config.odd_asr_cfg["asr_file_cfg"]["max_instance"]
    logger.info(f"=== 开始初始化ASR实例，计划创建 {max_instance} 个实例 ===")

    try:
        for i in range(max_instance):
            logger.debug(f"创建第 {i + 1}/{max_instance} 个ASR实例...")
            # 创建实例（内部会加载模型）
            odd_asr_file = OddAsrFile(odd_asr_params_file)
            instance_id = id(odd_asr_file)  # 实例唯一标识
            odd_asr_file_set.add(odd_asr_file)
            logger.debug(f"第 {i + 1} 个实例创建成功，ID: {instance_id}")

        # 验证实际创建数量
        actual_count = len(odd_asr_file_set)
        logger.info(f"=== ASR实例初始化完成，计划 {max_instance} 个，实际 {actual_count} 个 ===")
        if actual_count != max_instance:
            logger.warning(f"实例创建数量不匹配！可能部分实例初始化失败")

    except Exception as e:
        logger.error(f"=== ASR实例初始化失败: {str(e)} ===", exc_info=True)
        odd_asr_file_set.clear()  # 失败时清空实例池
        raise  # 终止服务启动，必须修复后才能继续


def find_free_odd_asr_file():
    """查找空闲的ASR实例，返回第一个非忙碌的实例"""
    global odd_asr_file_set
    total = len(odd_asr_file_set)

    # 检查实例池是否为空
    if total == 0:
        logger.error("查找空闲实例失败：实例池为空（未初始化或初始化失败）")
        return None

    # 遍历实例池检查状态
    busy_count = 0
    free_instance = None
    for odd_asr_file in odd_asr_file_set:
        instance_id = id(odd_asr_file)
        is_busy = odd_asr_file.is_busy()

        if is_busy:
            busy_count += 1
            logger.debug(f"实例 {instance_id} 状态：忙碌")
        else:
            logger.debug(f"实例 {instance_id} 状态：空闲（已找到）")
            free_instance = odd_asr_file
            break  # 找到第一个空闲实例即返回

    # 输出统计信息
    logger.info(f"查找结果：总实例 {total} 个，忙碌 {busy_count} 个，空闲 {total - busy_count} 个")
    if not free_instance:
        logger.warning("所有实例均忙碌，无可用资源")
    return free_instance


# 初始化Flask应用
app = Flask(__name__, static_url_path='')


def register_blueprints(new_app, path):
    """注册路由蓝图"""
    logger.info(f"开始注册蓝图，路径: {path}")
    try:
        for name in werkzeug.utils.find_modules(path):
            logger.debug(f"导入模块: {name}")
            module = werkzeug.utils.import_string(name)
            new_app.register_blueprint(module.bp)
            logger.debug(f"蓝图 {module.bp.name} 注册成功")
        # 注册异常处理器
        new_app.errorhandler(odd_asr_exceptions.CodeException)(
            odd_asr_exceptions.handler
        )
        logger.info("所有蓝图注册完成")
    except Exception as e:
        logger.error(f"蓝图注册失败: {str(e)}", exc_info=True)
        raise


# 注册路由（确保在app初始化后）
register_blueprints(app, 'router')

# Flask配置
app.config['SECRET_KEY'] = os.urandom(24)
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)
logger.debug("Flask应用配置完成")

# 导入路由模块（确保蓝图已注册）
import router.asr_api

logger.debug("ASR接口模块导入完成")

# 服务启动入口（若直接运行此文件）
if __name__ == '__main__':
    try:
        # 初始化ASR实例
        init_instance_file()
        # 启动Flask服务
        logger.info(f"启动Flask服务，地址: http://{config.HOST}:{config.PORT}")
        app.run(
            host=config.HOST,
            port=config.PORT,
            debug=config.DEBUG,
            threaded=True  # 启用多线程处理请求
        )
    except Exception as e:
        logger.critical(f"服务启动失败: {str(e)}", exc_info=True)
        exit(1)
